package simulador;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;
import java.util.concurrent.*;

import br.PopulacaoRunnable;

import model.Populacao;


public class Simulador {
	public static int NUM_OUTPUTS = 20;
	public static int NUM_THREADS = 4; //padrao deixar 4 = nucleos i5
	public static int NUM_AMOSTRAS = 5;
	
	public enum RedeOPT{POISSON, SCALEFREE;}
	
	public static void start(long raiz, double m, double theta, int D, int Nd, int numCiclos, int amostras,RedeOPT opcaoRede){
		
	}
	
 	public static void start(long raiz, double m, double theta, int D, int Nd, int numCiclos, RedeOPT opcaoRede){
		long start = System.currentTimeMillis();
		System.out.println("Start: ");
		
		int numPontos = NUM_OUTPUTS;
		int numAmostra = NUM_AMOSTRAS;
		
		System.out.println("invocation: m="+m+" theta="+theta+" D="+D+" Nd="+Nd+" Ciclos="+numCiclos);
		
		long[] media = new long[numPontos];
		
		ExecutorService ex = Executors.newFixedThreadPool(NUM_THREADS); //padrao deixar 4 = nucleos i5
		PopulacaoRunnable[] workers = new PopulacaoRunnable[numAmostra];
		
		Populacao [] amostras = new Populacao[numAmostra];
		
		for (int i = 0; i < numAmostra; i++) {
			Populacao p;
			if(opcaoRede == RedeOPT.SCALEFREE){
				p = new Populacao(raiz + i, m, theta, D, Nd); // usando scale-free
			}else{
				p = new Populacao(raiz + i, m, theta, D, Nd, 5); //usando random graph
			}
			amostras[i] = p;
			workers[i] = new PopulacaoRunnable(p, numCiclos, numPontos);
			ex.execute(workers[i]);
		}
		ex.shutdown();
		
		while(!ex.isTerminated());
		
		for(int i = 0; i< numPontos; i++){
			long med = 0L;
			for(int j = 0; j<numAmostra; j++){
				med += amostras[j].getHistoricoDiversidade()[i];
			}
			media[i] = med/numAmostra;
		}
		
		PrintWriter saida;
		try {
			saida = new PrintWriter(new FileWriter(new File("padroes.dat"),true));
			
			String novoPadrao = "";
			novoPadrao = novoPadrao.concat(m+","+theta+","+D+","+Nd+","+numCiclos);
			for(int j=0; j<media.length;j++){
				novoPadrao = novoPadrao.concat(","+media[j]);
			}
			
			saida.println("\n");
			saida.append(novoPadrao);
			saida.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		
		System.out.printf("Duration: %.2f minutos.",((double)(System.currentTimeMillis() - start)/60000));
	
	}
	
	public static void start(long raiz, int maxNumTheta, int maxD,int maxNd,RedeOPT opcaoRede){
	
		Random a = new Random(raiz);
		
		double m = 1;
		while( m > 0.3) m =a.nextDouble();
		
		double theta = a.nextInt(maxNumTheta);
		int D = a.nextInt(maxD);
		int Nd = a.nextInt(maxNd);
		int numCiclos = a.nextInt(10*Nd);
		
		start(raiz, m, theta, D, Nd, numCiclos, opcaoRede);

	}

	
	//usado na figura -2298 ---> 0.001, 5 , 100, 1000, 300000, Simulador.RedeOPT.SCALEFREE
	
	public static void main(String[] args) {
		
		Simulador.start(-9921, 0.001, 5 , 100, 500, 150000, Simulador.RedeOPT.SCALEFREE);
		
	}
	
}
